﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using TaoLeH.Helper.Json;

namespace TaoLeH.Helper
{
    /// <summary>
    /// 常用帮助类
    /// 作者：leev
    /// 时间：2018-01-02
    /// </summary>
    public class ApiHelper
    {
        #region 签名&加密

        /// <summary>
        /// 创建签名
        /// </summary>
        /// <param name="ht"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string CreateSign(Hashtable ht, string key)
        {
            StringBuilder strbuilder = new StringBuilder();
            ArrayList arrayList = new ArrayList(ht.Keys);
            arrayList.Sort();
            foreach (string k in arrayList)
            {
                string v = ht[k]?.ToString();
                if (null != v && "".CompareTo(v) != 0 && "sign".CompareTo(k.ToLower()) != 0 && "key".CompareTo(k.ToLower()) != 0)
                    strbuilder.Append(k.ToLower() + "=" + v + "&");
            }
            strbuilder.Append("key=" + key);

            string sign = Md5Encrypt(strbuilder.ToString(), Encoding.UTF8).ToLower();
            return sign;
        }

        /// <summary>
        /// 检查签名
        /// </summary>
        /// <returns></returns>
        public static bool CheckSign(Hashtable ht, string key)
        {
            string sign = CreateSign(ht, key);
            return GetHashTabValue(ht, "sign").ToLower().Equals(sign);
        }

        /// <summary>
        /// 获取hashtable值
        /// </summary>
        public static string GetHashTabValue(Hashtable hat, string name)
        {
            string s = (string)hat[name];
            return (null == s) ? "" : s;
        }

        /// <summary>
        /// 将字符串经过md5加密，返回加密后的字符串的小写表示
        /// </summary>
        public static string Md5Encrypt(string strToBeEncrypt, Encoding encoding)
        {
            MD5 md5 = new MD5CryptoServiceProvider();
            Byte[] FromData = encoding.GetBytes(strToBeEncrypt);
            Byte[] TargetData = md5.ComputeHash(FromData);
            string Byte2String = "";
            for (int i = 0; i < TargetData.Length; i++)
            {
                Byte2String += TargetData[i].ToString("x2");
            }
            return Byte2String.ToLower();
        }

        /// <summary>
        /// 	Encodes the input value to a Base64 string using the default encoding.
        /// </summary>
        /// <param name = "value">The input value.</param>
        /// <returns>The Base 64 encoded string</returns>
        public static string EncodeBase64(string value)
        {
            return EncodeBase64(value, null);
        }

        /// <summary>
        /// 	Encodes the input value to a Base64 string using the supplied encoding.
        /// </summary>
        /// <param name = "value">The input value.</param>
        /// <param name = "encoding">The encoding.</param>
        /// <returns>The Base 64 encoded string</returns>
        public static string EncodeBase64(string value, Encoding encoding)
        {
            encoding = (encoding ?? Encoding.UTF8);
            var bytes = encoding.GetBytes(value);
            return Convert.ToBase64String(bytes);
        }

        /// <summary>
        /// 	Decodes a Base 64 encoded value to a string using the default encoding.
        /// </summary>
        /// <param name = "encodedValue">The Base 64 encoded value.</param>
        /// <returns>The decoded string</returns>
        public static string DecodeBase64(string encodedValue)
        {
            encodedValue = encodedValue.Replace("\n", "").Replace(" ", "+");
            encodedValue = Regex.Unescape(encodedValue);
            return DecodeBase64(encodedValue, null);
        }

        /// <summary>
        /// 	Decodes a Base 64 encoded value to a string using the supplied encoding.
        /// </summary>
        /// <param name = "encodedValue">The Base 64 encoded value.</param>
        /// <param name = "encoding">The encoding.</param>
        /// <returns>The decoded string</returns>
        public static string DecodeBase64(string encodedValue, Encoding encoding)
        {
            encoding = (encoding ?? Encoding.UTF8);
            var bytes = Convert.FromBase64String(encodedValue);
            return encoding.GetString(bytes);
        }

        public static string ConvertToBase64Str(string str)
        {
            str = Regex.Unescape(str);
            return str.Replace("\r", "")
                            .Replace("\n", "")
                            .Replace(" ", "+");
        }

        #endregion 签名&加密

        /// <summary>
        /// 检查时间戳是否有效
        /// </summary>
        /// <param name="timeStamp"></param>
        /// <param name="timeValid">有效时间 单位：秒</param>
        /// <returns></returns>
        public static bool CheckTimeStamp(int timeStamp, int timeValid)
        {
            int nowTimeStamp = GetTimeStamp();
            if (Math.Abs(nowTimeStamp - timeStamp) > timeValid)
                return false;
            return true;
        }

        /// <summary>
        /// 获取Unix时间戳
        /// </summary>
        /// <returns></returns>
        public static int GetTimeStamp()
        {
            return ConvertTimeInt(DateTime.Now);
        }

        /// <summary>
        /// 返回标准时间格式string
        /// </summary>
        public static string GetDateTime()
        {
            return DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
        }

        /// <summary>
        /// DateTime时间格式转换为Unix时间戳格式
        /// </summary>
        /// <param name=”time”></param>
        /// <returns></returns>
        public static int ConvertTimeInt(System.DateTime time)
        {
            //System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
            DateTime startTime = TimeZoneInfo.ConvertTime(new System.DateTime(1970, 1, 1, 8, 0, 0), TimeZoneInfo.Local);
            return (int)(time - startTime).TotalSeconds;
        }

        /// <summary>
        /// 记录文本日志
        /// </summary>
        /// <param name="str">日志内容</param>
        /// <param name="path">文件物理地址</param>
        public static void WriteLog(string str, string path)
        {
            try
            {
                System.IO.StreamWriter sw = new System.IO.StreamWriter(path, true);
                sw.BaseStream.Seek(0, System.IO.SeekOrigin.End);
                sw.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " " + str);
                sw.Flush();
                sw.Close();
            }
            catch (Exception e)
            {
                throw e;
            }
        }
       
    }
}
